use serde::{Deserialize, Serialize};
use std::collections::HashMap;

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Instance {
    pub ip: String, //字符串	是	服务实例IP
    pub port: String,
    #[serde(alias = "namespaceId")]
    pub namespace_id: String, //字符串	否	命名空间ID
    pub weight: String,   //double	//否	权重
    pub enabled: String,  //boolean	//否	是否上线
    pub healthy: String,  //boolean	否	是否健康
    pub metadata: String, //字符串	否	扩展信息
    #[serde(alias = "clusterName")]
    pub cluster_name: String, //字符串	否	集群名
    #[serde(alias = "serviceName")]
    pub service_name: String, //字符串	是	服务名
    #[serde(alias = "groupName")]
    pub group_name: String, //字符串	否	分组名
    pub ephemeral: String, //boolean	否	是否临时实例
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct InstanceHealthy {
    pub ip: String, //字符串	是	服务实例IP
    pub port: String,
    #[serde(alias = "namespaceId")]
    pub namespace_id: String, //字符串	否	命名空间ID
    pub healthy: String,  //boolean	否	是否健康
    pub metadata: String, //字符串	否	扩展信息
    #[serde(alias = "clusterName")]
    pub cluster_name: String, //字符串	否	集群名
    #[serde(alias = "serviceName")]
    pub service_name: String, //字符串	是	服务名
    #[serde(alias = "groupName")]
    pub group_name: String, //字符串	否	分组名
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct InstanceQueryList {
    #[serde(alias = "serviceName")]
    pub service_name: String, //字符串	是	服务名
    #[serde(alias = "groupName")]
    pub group_name: String, //字符串	否	分组名
    #[serde(alias = "namespaceId")]
    pub namespace_id: String, //字符串	否	命名空间ID
    pub clusters: String, //字符串，多个集群用逗号分隔	否	集群名称
    #[serde(alias = "healthyOnly")]
    pub healthy_only: String, //boolean	否，默认为false	是否只返回健康实例
}

impl Default for InstanceQueryList {
    fn default() -> Self {
        Self {
            service_name: "service-job-gateway".to_string(),
            group_name: Default::default(),
            namespace_id: Default::default(),
            clusters: Default::default(),
            healthy_only: String::from("false"),
        }
    }
}
impl InstanceQueryList {}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct InstanceBeat {
    #[serde(rename = "serviceName")]
    pub service_name: Option<String>, //	字符串	是	服务名
    pub ip: Option<String>,   //	字符串	是	服务实例IP
    pub port: Option<String>, //	int	是	服务实例PORT
    #[serde(rename = "namespaceId")]
    pub namespace_id: String, //	字符串	否	命名空间ID
    #[serde(rename = "groupName")]
    pub group_name: String, //	字符串	否	分组名
    pub ephemeral: String,    //	boolean	否	是否临时实例
    pub beat: Option<String>, //	JSON格式字符串	是	实例心跳内容
}
#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Beat {
    pub cluster: String,
    pub ip: String,
    pub metadata: Option<HashMap<String, String>>,
    pub port: i32,
    pub scheduled: bool,
    #[serde(rename = "serviceName")]
    pub service_name: String,
    pub weight: i32,
}

impl Instance {}
impl Default for Instance {
    fn default() -> Self {
        Self {
            ip: "10.0.16.24".to_string(),
            port: "8082".to_string(),
            // namespace_id: "9fc0a68f-e3d3-4a49-a5b5-560665ac3f57".to_string(),
            namespace_id: Default::default(),
            weight: "1".to_string(),
            enabled: "true".to_string(),
            healthy: String::from("true"),
            metadata: Default::default(),
            cluster_name: "TEST1".to_string(),
            service_name: "test-service-2".to_string(),
            group_name: "DEFAULT_GROUP".to_string(),
            ephemeral: String::from("true"),
        }
    }
}

impl Default for InstanceHealthy {
    fn default() -> Self {
        Self {
            ip: "10.0.16.24".to_string(),
            port: "8082".to_string(),
            // namespace_id: "9fc0a68f-e3d3-4a49-a5b5-560665ac3f57".to_string(),
            namespace_id: Default::default(),
            healthy: String::from("true"),
            metadata: Default::default(),
            cluster_name: "".to_string(),
            service_name: "service-job-gateway".to_string(),
            group_name: "DEFAULT_GROUP".to_string(),
        }
    }
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct Service {
    #[serde(alias = "serviceName")]
    pub service_name: String, //	字符串	是	服务名
    #[serde(alias = "groupName")]
    pub group_name: String, //字符串	否	分组名
    #[serde(alias = "namespaceId")]
    pub namespace_id: String, //字符串	否	命名空间ID
    #[serde(alias = "protectThreshold")]
    pub protect_threshold: String, //浮点数	否	保护阈值,取值0到1,默认0
    pub metadata: String, //字符串	否	元数据
    pub selector: String, //JSON格式字符串	否	访问策略
}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ServiceListQuery {
    #[serde(alias = "pageNo")]
    pub page_no: String, //	int	是	当前页码
    #[serde(alias = "pageSize")]
    pub page_size: String, //	int	是	分页大小
    #[serde(alias = "groupName")]
    pub group_name: String, //	字符串	否	分组名
    #[serde(alias = "namespaceId")]
    pub namespace_id: String, //	字符串	否	命名空间ID
}
impl Default for ServiceListQuery {
    fn default() -> Self {
        Self {
            page_no: String::from("1"),
            page_size: String::from("100"),
            group_name: Default::default(),
            namespace_id: Default::default(),
        }
    }
}

impl ServiceListQuery {}

impl Default for Service {
    fn default() -> Self {
        Self {
            service_name: "test-service-2".to_string(),
            group_name: "DEFAULT_GROUP".to_string(),
            // namespace_id: "9fc0a68f-e3d3-4a49-a5b5-560665ac3f57".to_string(),
            namespace_id: Default::default(),
            protect_threshold: "0.5".to_string(),
            metadata: Default::default(),
            selector: Default::default(),
        }
    }
}
impl Service {}

#[derive(Debug, Deserialize, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
pub struct ServiceInfoRes {
    pub metadata: Option<HashMap<String, String>>,
    #[serde(rename = "groupName")]
    pub group_name: Option<String>,
    #[serde(rename = "namespaceId")]
    pub namespace_id: Option<String>,
    pub name: Option<String>,
    pub selector: Option<Selector>,
    #[serde(rename = "protectThreshold")]
    pub protect_threshold: Option<f32>,
    pub clusters: Vec<Cluster>,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Selector {
    #[serde(rename = "type")]
    #[serde(alias = "type")]
    pub select_type: String,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct Cluster {
    pub metadata: Option<HashMap<String, String>>,
    pub name: Option<String>,
    #[serde(rename = "healthChecker")]
    #[serde(alias = "healthChecker")]
    pub health_checker: Option<HealthChecker>,
}

#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct HealthChecker {
    #[serde(rename = "type")]
    #[serde(alias = "type")]
    pub select_type: String,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OperatorSwitches {
    pub entry: Option<String>, //	字符串	是	开关名
    pub value: Option<String>, //	字符串	是	开关值
    pub debug: Option<String>, //	boolean	否	是否只在本机生效,true表示本机生效,false表示集群生效
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct HttpHealthParams {
    max: Option<i64>,
    min: Option<i64>,
    factor: Option<f64>,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OperatorSwitchesRes {
    name: Option<String>,
    masters: Option<String>,
    ad_weight_map: Option<HashMap<String, String>>,
    default_push_cache_millis: Option<i64>,
    client_beat_interval: Option<i64>,
    default_cache_millis: Option<i64>,
    distro_threshold: Option<f64>,
    health_check_enabled: Option<bool>,
    distro_enabled: Option<bool>,
    enable_standalone: Option<bool>,
    push_enabled: Option<bool>,
    check_times: Option<i64>,
    http_health_params: Option<HttpHealthParams>,
    tcp_health_params: Option<HttpHealthParams>,
    mysql_health_params: Option<HttpHealthParams>,
    incremental_list: Vec<String>,
    server_status_synchronization_period_millis: Option<i64>,
    service_status_synchronization_period_millis: Option<i64>,
    disable_add_ip: Option<bool>,
    send_beat_only: Option<bool>,
    limited_url_map: Option<HashMap<String, String>>,
    distro_server_expired_millis: Option<i64>,
    push_go_version: Option<String>,
    push_java_version: Option<String>,
    push_python_version: Option<String>,
    push_cversion: Option<String>,
    enable_authentication: Option<bool>,
    overridden_server_status: Option<String>,
    default_instance_ephemeral: Option<bool>,
    health_check_white_list: Vec<String>,
    checksum: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct OperatorMetricsRes {
    service_count: Option<i64>,
    load: Option<f64>,
    mem: Option<f64>,
    responsible_service_count: Option<i64>,
    instance_count: Option<i64>,
    cpu: Option<f64>,
    status: Option<String>,
    responsible_instance_count: Option<i64>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OperatorMetrics {}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct OperatorServers {
    pub healthy: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct OperatorServersRes {
    servers: Option<Vec<Servers>>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Servers {
    ip: Option<String>,
    serve_port: Option<i64>,
    site: Option<String>,
    weight: Option<i64>,
    ad_weight: Option<i64>,
    alive: Option<bool>,
    last_ref_time: Option<i64>,
    last_ref_time_str: Option<String>,
    key: Option<String>,
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RaftLeader {}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Leader {
    heartbeat_due_ms: Option<i64>,
    ip: Option<String>,
    leader_due_ms: Option<i64>,
    state: Option<String>,
    term: Option<i64>,
    vote_for: Option<String>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct RaftLeaderRes {
    leader: Option<Leader>,
}
